"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 24、执行javascript脚本.py
"""

# 遇到页面无法定位的元素，用 selenium 直接对javascript进行操作（selenium更强大的能力）
"""
JavaScript 简介
    ========================    JavaScript 是一种具有函数优先的轻量级，解释型或即时编译型的编程语言  ====================
    ========================   可以嵌入到 HTML 页面对浏览器事件做出响应  ==================================
    也可以基于 Node.js 技术进行服务端编程
    
    使用场景 ； 部分元素使用 selenium 原生方法无法解决
        修改时间控件
        滚动到某个元素
        其他场景
    JavaScript 使用思路：
        1. 页面调式 js 脚本  - >  进入 console 调式
        2. Selenium 执行 js  -> js 脚本如果有返回值则会在浏览器返回
    
    执行 dom 相关的操作
        点击操作
        滚动操作
        属性修改
        

常用 JavaScript 脚本
js脚本元素操作：
    通过 css 查找元素
        元素点击       ->    document.querySelector("#site-logo")
        input标签 修改元素的属性(类似 send_keys 操作)  ->   document.querySelector('#kw').value = '霍格沃兹测试学院'
            修改时间格式 ： document.querySelector("#train_date").value = "2023-10-03"
        按钮点击       ->     document.querySelector('#su').click()
        元素的类属性   ->    document.querySelector("#J_SiteNavMytaobao").className  ->   
            不悬停时：'site-nav-menu site-nav-mytaobao site-nav-multi-menu J_MultiMenu '
            悬停时： 'site-nav-menu site-nav-mytaobao site-nav-multi-menu J_MultiMenu site-nav-menu-hover'
        获取元素的文本属性 ->  document.querySelector("#ember63").innerText
            修改测试人社区的 开源项目 为 开源 -> document.querySelector("#ember41").innerHTML="开源"
        如果是多个操作（例如百度框 修改搜索内容为 霍格沃兹测试学院，再点击。用英文;连接）
            document.querySelector('#kw').value = '思寒';document.querySelector('#su').click()
        滚动操作：
            页面滚动到底部  ->    document.documentElement.scrollTop=10000
            指定到滚动的位置 ->  document.querySelector("css表达式").scrollIntoView();

selenium 执行 JavaScript
    execute_script ： 
        执行js
    在 js 语句中添加 return ： 代码可以获取js的执行结果
        document.title  打印页面标题：'百度一下，你就知道'
        JSON.stringify(performance.timing) 获取界面的一些性能数据
        document.documentElement.scrollTop=10000   滑动到页面最底端

JavsScript 操作案例
"""
# selenium调用js
import time
from selenium import webdriver
from selenium.webdriver.common.by import By


class Test_js:
    # 用例前置：打开浏览器
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        # 设置隐式等待 : 10s
        self.driver.implicitly_wait(10)

    # 用例后置：关闭浏览器
    def teardown(self):
        self.driver.quit()

    #  ===========================   案例一 ： 通过属性修改展示下拉框  1、打开淘宝首页  2、修改下拉框属性  =================
    def test_select_down(self):
        # 打开网址
        self.driver.get('https://www.taobao.com/')
        # 修改下拉框属性
        # 通过窗口冻结断点浏览器，setTimeout(function(){debugger},3000)
        time.sleep(2)
        # 悬停到我的宝贝
        self.driver.execute_script(
            "document.querySelector('#J_SiteNavMytaobao').className='site-nav-menu site-nav-mytaobao site-nav-multi-menu J_MultiMenu site-nav-menu-hover'")
        time.sleep(2)
        # 点击 已买到的宝贝
        self.driver.find_element(By.XPATH, "//*[text()='已买到的宝贝']").click()
        time.sleep(3)

        # ====================  案例二 ：滑动到页面底部 ： 打开百度，输入selenium测试，点击搜索，滑动到最底部，点击下一页  =======================

    def test_ceshiren_grid(self):
        hogwarts_grid_url = "https://selenium-node.hogwarts.ceshiren.com/wd/hub"
        capabilities = {'browserName': 'chrome', 'browserVersion': '99.0'}
        # 通过 desired_capabilities 添加配置信息
        self.driver = webdriver.Remote(command_executor=hogwarts_grid_url, desired_capabilities=capabilities)
        self.driver.get('https://www.ceshiren.com')
        text = self.driver.find_element(By.CSS_SELECTOR, '.login-button').text
        print(text)
        time.sleep(3)

    def test_js_scroll(self):
        self.driver.get('https://www.baidu.com')
        self.driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("selenium测试")
        # 直接使用js 操作，定位到百度的搜索按钮并点击
        ele = self.driver.execute_script("return document.getElementById('su')")
        ele.click()
        # 调用 Js ，滑动到百度页面最底部：显示出下一页
        self.driver.execute_script("document.documentElement.scrollTop=10000")
        time.sleep(3)
        # 点击下一页
        self.driver.find_element(By.XPATH, "//*[@class='n' and contains(text(),'下一页')]").click()
        time.sleep(3)

        # js的其他操作：获取页面标题，和获取性能相关的信息
        for code in ['return document.title', 'return JSON.stringify(performance.timing)']:
            print(self.driver.execute_script(code))
        assert self.driver.title == 'selenium测试_百度搜索'


# 操作js 来处理时间控件：大部分的时间控件都是readonly属性
"""
1。取消日期的 readonly 属性
2、给 value 赋值
3、用 webdriver 对 js 进行处理 

    修改12306日期
    一：定位出日期并赋值：department = document.getElementById('train_date')
    二：去掉只读属性：department.removeAttribute('readonly')
    三：设定新的出发日期：department.value='2022-03-26'
"""


# 案例三 ：时间控件 - 通过属性修改时间控件的值   1、打开12306 2、修改时间控件值  3、打印出发日期
# 在 12306 上修改出发日期  train_date

def test_modity_12306_js():
    """
    1、打开12306
    2、修改时间控件值
    3、打印出发日期
    """
    driver = webdriver.Chrome()
    driver.get('https://www.12306.cn/index/')
    driver.implicitly_wait(10)
    driver.maximize_window()

    # 修改时间控件的信息
    driver.execute_script("document.querySelector('#train_date').value = '2023-10-03'")
    # 获取时间控件的信息，并返回出来
    date_data = driver.execute_script("return document.querySelector('#train_date').value")
    print(f"获取的时间控件信息为{date_data}")
    time.sleep(3)
